#include "stdinclude.h"
#include "core/AppRoot.h"
#include "core/MainLoop.h"
#include "input/InputSys.h"
#include "gfx/GfxSys.h"
#include "phy/PhySys.h"
////////////////////////////////////////

//ENGINE_API AppRoot APPROOT;

////////////////////////////////////////

AppRoot::AppRoot(void)
{
}


AppRoot::~AppRoot(void)
{	
	
}


// punto di ingresso applicazione

void AppRoot::main(PlatformData platformData)
{	
	try
	{
		init(platformData);
		{		
			runResourceLoader();
			{
				runMainLoop();
				{

				}
			
			}
		
		}		
	}
	catch(CoreException & e)
	{
		_error("Errore di esecuzione AppRoot::main: " + e.what());		
	}
	catch (std::exception& e)
	{
		_error("Errore di esecuzione AppRoot::main: " + String(e.what()));		
	}
	catch(...)
	{
		_error("Errore di esecuzione AppRoot::main");
	}
	end();
}

static void _throwInitException(const String& name,const String& what)
{
	throw InitException ("errore di inizializzazione del sottosistema: " + name +" : "+what);	
}

int AppRoot::init(PlatformData platformData) throw (InitException)
{ 		
	_dbgout("APPROOT init \n");
	
	this->platformData = platformData;

	options.load();	
	
	//init core subsystems
	subsystemList.push_back(std::unique_ptr<ISubsystem>(new InputSys(this)) );
	subsystemList.push_back(std::unique_ptr<ISubsystem>(new GfxSys(this)) );
	subsystemList.push_back(std::unique_ptr<ISubsystem>(new PhySys(this)) );

	for (AppSubsystemList::iterator it = subsystemList.begin(); it!=subsystemList.end();++it )
	{
		String nomeSottosistema= it->get()->getClassName();
		try
		{
			_dbgout("inizializzazione sottosistema: "+nomeSottosistema+"\n");
			it->get()->init(platformData);
		}
		catch(CoreException& e)
		{
			_throwInitException ( nomeSottosistema, e.what());			
		}
		catch (std::exception& e)
		{
			_throwInitException ( nomeSottosistema, e.what());		
		}  
		catch(...)
		{
			_throwInitException ( nomeSottosistema,"");		
		}
	}

	return 0;
}


int AppRoot::runResourceLoader(void)
{	
	return 0;
}


// esecuzione principale del gioco
int AppRoot::runMainLoop(void)
{	
	
	////////////////////	

	_dbgout("APPROOT runMainLoop \n");
	mainLoop.execute();	

	mainLoop.removeAll();

	////////////////////
	

	return 0;
}




// chiusura e libera risorse
int AppRoot::end(void)
{	
	_dbgout("APPROOT shooting down subsystems \n");

	for(AppSubsystemList::iterator it = subsystemList.begin(); it!=subsystemList.end(); ++it)
	{
		(*it)->shutdown();
	}
	
	subsystemList.clear();

	_dbgout("APPROOT end \n");
	return 0;
}




MainLoop& AppRoot::getMainLoop()
{
	return mainLoop;
}